package com.dormitory.management.system.utils;


import cn.hutool.core.lang.Assert;
import com.alipay.easysdk.factory.Factory;
import com.alipay.easysdk.kernel.util.ResponseChecker;
import com.alipay.easysdk.payment.app.models.AlipayTradeAppPayResponse;
import com.alipay.easysdk.payment.common.models.AlipayTradeCloseResponse;
import com.alipay.easysdk.payment.common.models.AlipayTradeQueryResponse;
import com.alipay.easysdk.payment.common.models.AlipayTradeRefundResponse;
import com.alipay.easysdk.payment.facetoface.models.AlipayTradePrecreateResponse;
import com.alipay.easysdk.payment.page.models.AlipayTradePagePayResponse;
import com.alipay.easysdk.payment.wap.models.AlipayTradeWapPayResponse;
import com.dormitory.management.system.entity.Cost;
import com.dormitory.management.system.enums.CostEnum;
import com.dormitory.management.system.mapper.CostMapper;
import lombok.extern.log4j.Log4j;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

@Component
@Log4j2
public class AliPayUtil {
    @Autowired
    private CostMapper costMapper;
    /**
     * app支付
     *
     * @param subject     订单标题
     * @param outTradeNo  交易创建时传入的商户订单号
     * @param totalAmount 订单总金额，单位为元，精确到小数点后两位，取值范围[0.01,100000000]
     * @return
     */
    public AlipayTradeAppPayResponse appPay(String subject, String outTradeNo, String totalAmount) {
        AlipayTradeAppPayResponse alipayTradeAppPayResponse = null;
        try {
            alipayTradeAppPayResponse = Factory.Payment.App().pay(subject, outTradeNo, totalAmount);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (Objects.isNull(alipayTradeAppPayResponse)) {
            throw new RuntimeException("数据为空，支付失败");
        }
        return alipayTradeAppPayResponse;
    }

    /**
     *当面付
     * @param outTradeNo  订单编号（唯一）
     * @param totalAmount 订单价格
     * @param subject     商品名称
     */
    public String faceToFacePay(String subject, String outTradeNo, String totalAmount) {
        try {
            AlipayTradePrecreateResponse response = Factory.Payment.FaceToFace().preCreate(subject, outTradeNo, totalAmount);
            if (ResponseChecker.success(response)) {
                log.info("调用成功");
                return response.getQrCode();
            } else {
                log.error("调用失败，原因" + response.msg);
            }
        } catch (Exception e) {
            log.error("调用发生异常，原因" + e.getMessage());
        }
        return null;
    }
    /**
     * 支付异步回调
     * @param request
     * @return
     */
    public String notifyUrl(HttpServletRequest request) {
        System.out.println(request);
        Map<String,String> map= new HashMap();
        Enumeration<String> parameterNames = request.getParameterNames();
        while(parameterNames.hasMoreElements()){
            String key = parameterNames.nextElement();
            String value = request.getParameter(key);
            map.put(key, value);
        }
        System.out.println(map);
        //验签
        try {
            if(Factory.Payment.Common().verifyNotify(map)){
                log.info("异步通知验签通过");
                //验证用户的支付结果
                String trade_status = request.getParameter("trade_status");
                if(trade_status.equals("TRADE_SUCCESS")){
                    log.info("支付交易成功");
                    //更新水电缴费状态
                    Cost cost = new Cost();
                    cost.setId(Long.valueOf(map.get("out_trade_no").substring(14)));
                    cost.setStatus(CostEnum.COST_PAID.getStatusId());
                    cost.setGmtEnd(new Date());
                    costMapper.updateById(cost);
                }
            }else {
                log.error("异步通知验签失败");
                return "支付失败";
            }
        } catch (Exception e) {
            log.error("异步发生异常{}",e.getMessage());
            return "支付失败";
        }
        return "支付成功";
    }

    /**
     * 手机网站支付
     *
     * @param subject:     订单标题
     * @param outTradeNo:  交易创建时传入的商户订单号
     * @param totalAmount: 订单总金额，单位为元，精确到小数点后两位，取值范围[0.01,100000000]
     * @param quitUrl:     用户付款中途退出返回商户网站的地址
     * @param returnUrl    支付成功后同步跳转的页面，是一个http/https开头的字符串
     * @return
     */
    public AlipayTradeWapPayResponse wapPay(String subject, String outTradeNo, String totalAmount, String quitUrl, String returnUrl) {
        AlipayTradeWapPayResponse alipayTradeWapPayResponse = null;
        try {
            // 主要操作 Factory.Payment.App().pay(subject, outTradeNo, totalAmount); 其他代码是一些判空以及异常处理
            alipayTradeWapPayResponse = Factory.Payment.Wap().pay(subject, outTradeNo, totalAmount, quitUrl, returnUrl);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (Objects.isNull(alipayTradeWapPayResponse)) {
            throw new RuntimeException("数据为空，支付失败");
        }

        return alipayTradeWapPayResponse;
    }

    /**
     * 扫码支付
     *
     * @param subject:     订单标题
     * @param outTradeNo:  交易创建时传入的商户订单号
     * @param totalAmount: 订单总金额，单位为元，精确到小数点后两位，取值范围[0.01,100000000]
     * @param returnUrl    支付成功后同步跳转的页面，是一个http/https开头的字符串
     * @return
     */
    public AlipayTradePagePayResponse pagePay(String subject, String outTradeNo, String totalAmount, String returnUrl) {
        AlipayTradePagePayResponse alipayTradePagePayResponse = null;
        try {
            alipayTradePagePayResponse = Factory.Payment.Page().pay(subject, outTradeNo, totalAmount, returnUrl);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (Objects.isNull(alipayTradePagePayResponse)) {
            throw new RuntimeException("数据为空，支付失败");
        }
        return alipayTradePagePayResponse;

    }




    /**
     * 支付查询
     *
     * @param outTradeNo 交易创建时传入的商户订单号
     * @return
     */
    public AlipayTradeQueryResponse query(String outTradeNo) {
        AlipayTradeQueryResponse alipayTradeQueryResponse = null;
        try {
            alipayTradeQueryResponse = Factory.Payment.Common().query(outTradeNo);
        } catch (Exception e) {
            e.printStackTrace();
        }
        Assert.isTrue(ResponseChecker.success(alipayTradeQueryResponse));
        return alipayTradeQueryResponse;

    }

    /**
     * 退款
     *
     * @param outTradeNo   交易创建时传入的商户订单号
     * @param refundAmount 退款金额
     * @return
     */
    public AlipayTradeRefundResponse refund(String outTradeNo, String refundAmount) {
        AlipayTradeRefundResponse alipayTradeRefundResponse = null;
        try {
            alipayTradeRefundResponse = Factory.Payment.Common().refund(outTradeNo, refundAmount);
        } catch (Exception e) {
            e.printStackTrace();
        }
        Assert.isTrue(ResponseChecker.success(alipayTradeRefundResponse));
        return alipayTradeRefundResponse;

    }

    /**
     * 取消交易
     *
     * @param outTradeNo 交易创建时传入的商户订单号
     * @return
     */
    public AlipayTradeCloseResponse close(String outTradeNo) {
        AlipayTradeCloseResponse alipayTradeCloseResponse = null;
        try {
            alipayTradeCloseResponse = Factory.Payment.Common().close(outTradeNo);
        } catch (Exception e) {
            e.printStackTrace();
        }
        Assert.isTrue(ResponseChecker.success(alipayTradeCloseResponse));
        return alipayTradeCloseResponse;
    }
}
